package com.food.restaurantpro.observers;

import java.util.ArrayList;
import java.util.Observable;
import java.util.Observer;

import com.food.restaurantpro.R;
import com.food.restaurantpro.RestaurantApp;
import com.food.restaurantpro.connection.DataHelper;
import com.food.restaurantpro.connection.DataResult;
import com.food.restaurantpro.database.tables.PromotionTable;
import com.food.restaurantpro.log.Log;
import com.food.restaurantpro.managingnetwork.ManagingNetwork;
import com.food.restaurantpro.objects.Promotion;
import com.food.restaurantpro.objects.PromotionForUpdate;
import com.food.restaurantpro.utils.Prefs;

public class PromotionObserver implements Observer {

	private PromotionObserver _me = this;
	private boolean hadRegisterObserver = false;
	private ArrayList<Promotion> mPromotionArrayList;
	private ArrayList<String> mPromotionIDList;
	//dung de save ngay-gio update promotions
	private Prefs mPref;
	// this interface return promotionlist to update UI of activity
	private PromotionObserverInterface mProInterface;
	
	public PromotionObserver(PromotionObserverInterface proInterface) {
		mProInterface = proInterface;
		mPref = new Prefs(RestaurantApp.CURRENT_CONTEXT);
	}

	/**
	 * register observer and get promotion list
	 * Khi lan dau tien vao app thi goi api getAllPromotions
	 * Lan thu 2 tro di thi goi api getUpdatePromotion
	 */
	public void registerObserver() {
		String dateUpdate = mPref.getStringValue(null, Prefs.KEY_DAY_UPDATE_PROMOTIONS);
		String timeUpdate = mPref.getStringValue(null, Prefs.KEY_TIME_UPDATE_PROMOTIONS);
		//get all id of promotions in database
		mPromotionIDList = PromotionTable.getAllPromotionID();
		//check neu chua co du lieu thi get all promotions after insert to database
		if (mPromotionIDList == null || mPromotionIDList.size() == 0
				|| dateUpdate == null || dateUpdate.equalsIgnoreCase("")
				|| timeUpdate == null || timeUpdate.equalsIgnoreCase("")) {
			// call api get all promotions
			if (ManagingNetwork.isNetworkAvailable()) {
				// show progress
				hadRegisterObserver = true;
				DataHelper.getInstance().addObserver(_me);
				DataHelper.getInstance().getAllPromotions();

			} else {
				// Lan dau tien vao app va khong co network, return null
				mProInterface.promotionListCallback(null, RestaurantApp.CURRENT_CONTEXT.getString(R.string.NETWORK_ERROR));
			}
		} else {
			// call api update promotion
			if (ManagingNetwork.isNetworkAvailable()) {
				// show progress
				hadRegisterObserver = true;
				String strProID = "";
				for(int i = 0; i < mPromotionIDList.size(); i++) {
					strProID += mPromotionIDList.get(i) + ",";
				}
				String proId = strProID.substring(0, strProID.length()-1);
				
				DataHelper.getInstance().addObserver(_me);
				DataHelper.getInstance().getUpdatePromotion(dateUpdate + "%20" + timeUpdate, proId);
			} else {
				//get all promotions in database: offline
//				mPromotionArrayList = PromotionTable.getAllPromotions();
				//cai nay da doi lai: chi lay danh sach promotion duoc thay doi tu server
				mProInterface.promotionListCallback(mPromotionArrayList, null);
			}
		}
	}

	/**
	 * must call this method in onDestroy of Activity which called
	 * registerObserver
	 */
	public void unRegisterObserver() {
		if (hadRegisterObserver) {
			DataHelper.getInstance().deleteObserver(_me);
			hadRegisterObserver = false;
		}
	}

	@SuppressWarnings("unchecked")
	@Override
	public void update(Observable observable, Object data) {
		// close progress
		if (data == null)
			return;
		DataResult result = (DataResult) data;
		switch (result.getMethodName()) {
		case getAllPromotions:
			if (result.getErrorCode() != null) {
				// show error mesage
				mProInterface.promotionListCallback(null, result.getErrorCode().getErrorMessage());
			} else {
				mPromotionArrayList = (ArrayList<Promotion>) result.getData();
				if (mPromotionArrayList != null) {
					PromotionTable.deleteAll();
					PromotionTable.insertListPromotions(mPromotionArrayList);
					//Save ngay-gio update promotions
					String currentDay = mPref.getStringValue(null, Prefs.KEY_CURRENT_DAY);
					String currentTime = mPref.getStringValue(null, Prefs.KEY_CURRENT_TIME);
					if(currentDay != null && currentTime != null) {
						mPref.putStringValue(currentDay, Prefs.KEY_DAY_UPDATE_PROMOTIONS);
						mPref.putStringValue(currentTime, Prefs.KEY_TIME_UPDATE_PROMOTIONS);
					}
					Log.i("PromotionObserver", "update() getAllPromotions",
							"currentDay = " + currentDay + ", currentTime = "
									+ currentTime);
					//
					mProInterface.promotionListCallback(mPromotionArrayList, null);
				} else {
					mProInterface.promotionListCallback(null,	RestaurantApp.CURRENT_CONTEXT.getResources()
									.getString(R.string.SERVER_ERROR));
				}
			}
			unRegisterObserver();
			break;
		case getUpdatePromotion:
			if (result.getErrorCode() != null) {
				//get all promotions in database
//				mPromotionArrayList = PromotionTable.getAllPromotions();
				//cai nay da doi lai: chi lay danh sach promotion duoc thay doi tu server
				// show error code
				mProInterface.promotionListCallback(mPromotionArrayList, result.getErrorCode().getErrorMessage());
			} else {
				PromotionForUpdate proUpdate = (PromotionForUpdate) result.getData();
				if (proUpdate != null) {
					//update database: insert, update, delete after get new list
					ArrayList<Promotion> proList = proUpdate.getPromotionList();
					ArrayList<String> proIdList = proUpdate.getPromotionIdList();
					
					//update
					if(proList != null) {
						boolean isUpdate = false;
						for(int i = 0; i < proList.size(); i++) {
							Promotion pro = proList.get(i);
							isUpdate = false;
							for(int j = 0; j < mPromotionIDList.size(); j++) {
								//new id = old id: update
								if(pro.getPromotionId().equalsIgnoreCase(mPromotionIDList.get(j))) {
									PromotionTable.updatePromotionByID(pro);
									isUpdate = true;
									break;
								}
							}
							//insert
							if(isUpdate == false) {
								PromotionTable.insertPromotion(pro);
							}
						}
					}
					
					//delete proId in database
					if(proIdList != null) {
						for(int i = 0; i < proIdList.size(); i++) {
							PromotionTable.deletePromotionByID(proIdList.get(i));
						}
					}
					//Save ngay-gio update promotions
					String currentDay = mPref.getStringValue(null, Prefs.KEY_CURRENT_DAY);
					String currentTime = mPref.getStringValue(null, Prefs.KEY_CURRENT_TIME);
					if(currentDay != null && currentTime != null) {
						mPref.putStringValue(currentDay, Prefs.KEY_DAY_UPDATE_PROMOTIONS);
						mPref.putStringValue(currentTime, Prefs.KEY_TIME_UPDATE_PROMOTIONS);
					}
					//
					Log.i("PromotionObserver", "update() getUpdatePromotion",
							"currentDay = " + currentDay + ", currentTime = "
									+ currentTime);
					//get all promotions in database
//					mPromotionArrayList = PromotionTable.getAllPromotions();
					//cai nay da doi lai: chi lay danh sach promotion duoc thay doi tu server
					mProInterface.promotionListCallback(proList, null);
				} else {
					//get all promotions in database
//					mPromotionArrayList = PromotionTable.getAllPromotions();
					//cai nay da doi lai: chi lay danh sach promotion duoc thay doi tu server
					mProInterface.promotionListCallback(mPromotionArrayList, null);
				}
			}
			unRegisterObserver();
			break;
		default:
			break;
		}
		// Chu y: Observer se post notification den tat ca cac lop da register
		// observer. Va cho nao co phuong thuc trung voi phuong thuc no tra ve thi xu ly
		// cho do, nhung cho khac ko xu ly, vi vay PHAI dat code o trong "case method:"
		//khong dat code o ngoai nay
	}

}
